package cn.tedu.submarine;
import javax.swing.JFrame;
import javax.swing.JPanel;//1.
import java.awt.Graphics;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Random;
import java.util.Arrays;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
/*整个游戏窗口*/
public class World extends JPanel{//2.
    public static final int WIDTH = 641;//窗口宽
    public static final int HEIGHT = 479;//窗口高

    public static final  int START = 0;//启动状态
    public static final  int RUNNING = 1;//运行状态
    public static final  int GAME_OVER = 2;//游戏结束
    private int state = START;//当前状态(默认为启动状态)

    private Battleship ship = new Battleship();//战舰
    private SeaObject[] submarines = {
    };     //潜艇(侦查潜艇,鱼雷潜艇,水雷潜艇)数组
    private SeaObject[] thunders ={
    };     //雷(鱼雷水雷)数组
    private Bomb[] boms ={
    };     //深水炸弹

    /**生成潜艇(侦查艇,鱼雷艇,水雷艇)对象*/
    public SeaObject nextSubmarine(){
        Random random = new Random();//随机数对象
        int type = random.nextInt(20);//0到19
        if (type<10){//0到9时,返回侦查潜艇对象
            return new ObserveSubmarine();
        }else if (type<16){//10到15时,返回鱼雷潜艇对象
            return new TorpedoSubmarine();
        }else {//16-19时返回水雷潜艇对象
            return new MineSubmarine();
        }
    }
    private int subEnterIndex = 0;//潜艇入场计数
    /**潜艇(侦查潜艇,鱼雷潜艇,水雷潜艇)入场*/
    public void submarineEnterAction(){//每10毫秒走一次
        subEnterIndex++;//每10毫秒增加1
        if (subEnterIndex%40==0){//每400(10*40)毫秒走一次
            SeaObject obj = nextSubmarine();//获取潜艇对象
            submarines = Arrays.copyOf(submarines,submarines.length+1);
            submarines[submarines.length-1] = obj;//将obj添加到submarine末尾
        }
    }

    private  int thunderEnterIndex = 0;//雷入场的次数
    /**雷(鱼雷水雷)入场*/
    public void thunderEnterAction(){//每10毫秒走一次
        thunderEnterIndex++;//每10毫秒
        if (thunderEnterIndex%100==0){//每1000毫秒走一次
            for (int i=0;i<submarines.length;i++){//遍历所以潜艇
                SeaObject obj = submarines[i].shootThunder();//获取潜艇发出来的雷
                if (obj!=null){//有雷
                    thunders = Arrays.copyOf(thunders,thunders.length+1);
                    thunders[thunders.length-1] = obj;//将发射出的雷obj添加到thunders
                }
            }
        }

    }

    /**海洋对象移动*/
    public void moveAction(){//每10毫秒走一次
        for (int i=0;i<submarines.length;i++){//遍历所以的潜艇
            submarines[i].move();//潜艇移动
        }
        for (int i=0;i<thunders.length;i++){//遍历所以的雷
            thunders[i].move();//雷移动
        }
        for (int i=0;i<boms.length;i++){//遍历所以的深水炸弹
            boms[i].move();//深水炸弹移动
        }
    }

    /**删除越界的海洋对象*/
    public void outOfBoundsAction(){//每10毫秒运行一次
        for (int i=0;i<submarines.length;i++){//遍历所以的潜艇
            if (submarines[i].isOutOfBounds() || submarines[i].isDEAD()){//越界了,或者,是死了的
                submarines[i] = submarines[submarines.length-1];
                submarines = Arrays.copyOf(submarines,submarines.length-1);
            }
        }

        for (int i=0;i<thunders.length;i++){
            if (thunders[i].isOutOfBounds() || thunders[i].isDEAD()){
                thunders[i] = thunders[thunders.length-1];
                thunders = Arrays.copyOf(thunders,thunders.length-1);
            }
        }

        for (int i=0;i<boms.length;i++){
            if (boms[i].isOutOfBounds() || boms[i].isDEAD()){
                boms[i] = boms[boms.length-1];
                boms = Arrays.copyOf(boms,boms.length-1);
            }
        }
    }

    private int score = 0;//玩家得得分
    /**深水炸弹与潜艇的碰撞*/
    public void bombBangAction(){//每10毫秒走一次
        for (int i=0;i<boms.length;i++){//遍历所以深水炸弹
            Bomb b =  boms[i];//获取每一个深水炸弹
            for (int j=0;j<submarines.length;j++){//遍历所以潜艇
                SeaObject s = submarines[j];//获取每一个潜艇
                if (b.isLive() && s.isLive() && s.isHit(b)){//若都活着并且撞上
                    s.geDead();//潜艇去死
                    b.geDead();//深水炸弹去死
                    if (s instanceof EnemyScore){//若被撞潜艇得分
                        EnemyScore es =(EnemyScore)s;//则被撞潜艇窗口强转成得分窗口
                        score += es.getScore();//玩家得分
                    }
                    if (s instanceof EnemyLife){//若被撞潜艇得命
                        EnemyLife el =(EnemyLife)s;//则被撞潜艇窗口强转成得命窗口
                        int num =el.getLife();//获得命数
                        ship.addLift(num);//战舰增命
                    }
                }
            }
        }
    }

    /**雷与战舰发生碰撞*/
    public void thunderBangAction(){//每10毫秒走一次
        for (int i=0;i<thunders.length;i++){//遍历所有的雷
            SeaObject t = thunders[i];//获取每一个雷
            if (t.isLive() && ship.isLive() && t.isHit(ship)){
                t.geDead();//雷去死
                ship.subtractLife();//战舰减命
            }
        }
    }

    /**检测游戏结束*/
    public void checkGameOverAction(){
        if (ship.getLife()<=0){//若战舰命数<=0，表示游戏结束
            state = GAME_OVER;//将当前状态修改为游戏结束
        }
    }
    /**启动程序的执行*/
    public void action(){
        KeyAdapter k = new KeyAdapter() {
            @Override/** 重写keyReleased键盘按键抬起事件*/
            public void keyReleased(KeyEvent e) {//键盘抬起自动发射的事件
                if (e.getKeyCode()==KeyEvent.VK_SPACE){//若按下的空格键
                    switch (state){//根据当前状态做出不同的事
                        case START://启动状态时,修改为运行状态
                            state = RUNNING;
                            break;
                        case RUNNING://运行状态时,发射深水炸弹
                            Bomb obj = ship.shoot();//获取战舰发射的深水炸弹
                            boms = Arrays.copyOf(boms,boms.length+1);
                            boms[boms.length-1] = obj;//将深水炸弹添加到最后 一位
                            break;
                        case GAME_OVER://游戏结束状态时,修改为启动状态
                            score = 0;//清理现场
                            ship = new Battleship();
                            submarines = new SeaObject[0];
                            thunders = new SeaObject[0];
                            boms = new Bomb[0];
                            state = START;
                            break;
                    }

                }
                if (e.getKeyCode()==KeyEvent.VK_LEFT){//若按下的左键
                    ship.moveLeft();//战舰左移
                }
                if(e.getKeyCode()==KeyEvent.VK_RIGHT){//若按下的右键
                    ship.moveRight();//战舰右移
                }
            }
        };
        //侦听器对象
        this.addKeyListener(k);//添加侦听

        Timer timer = new Timer();//定时器对象
        int  interval = 10;//定时间隔(以毫米为单位)
        timer.schedule(new TimerTask() {
            @Override
            public void run() {//表示定时干的那个事(每 10毫秒自动执行)
                if (state==RUNNING){//仅在运行状态运行
                    submarineEnterAction();//潜艇(侦查潜艇,鱼雷水雷潜艇)
                    thunderEnterAction();//雷(鱼雷水雷)入场
                    moveAction();        //海洋对象移动
                    outOfBoundsAction(); //删除越界的海洋对象
                    bombBangAction();    //深水炸弹与潜艇发生碰撞
                    thunderBangAction(); //雷与战舰得碰撞
                    checkGameOverAction();//检测游戏结束
                }
                repaint();           //自动调用paint()方法
            }
        },interval,interval);//定时计划表
    }


    /**重写paint()画 g:画笔*/
    public void paint(Graphics g){
        switch (state){//根据当前状态不同的处理
            case START://启动状态画启动图
                Images.start.paintIcon(null,g,0,0);
                break;
            case GAME_OVER://游戏结束状态画游戏的结束图
                Images.gameover.paintIcon(null,g,0,0);
                break;
            case RUNNING://运行状态时....
                Images.sea.paintIcon(null,g,0,0);//画海洋图
                ship.paintImage(g);//画战舰
                for (int i=0;i<submarines.length;i++){//遍历所以潜艇
                    submarines[i].paintImage(g);//画潜艇
                }
                for (int i=0;i<thunders.length;i++){//遍历所以雷
                    thunders[i].paintImage(g);//画雷
                }
                for (int i=0;i<boms.length;i++){//遍历所以深水炸弹
                    boms[i].paintImage(g);//画深水炸弹
                }
                g.drawString("SCORE :"+score,200,50);
                g.drawString("LIFE: "+ship.getLife(),400,50);
        }



    }

    public static void main(String[] args) {
        JFrame frame =  new JFrame();
        World world = new World();
        world.setFocusable(true);
        frame.add(world);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(World.WIDTH+16,World.HEIGHT+39);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);//1.设置窗口可见2.尽快自动调用paint()方法

        world.action();//启动程序的执行
    }
}
